package com.woniu.woniuYoga.handler;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniu.woniuYoga.comm.core.exception.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author: 付宽成
 * @description: gateway 的统一异常处理
 * @date: 2020/8/25 14:31
 * @version: 1.0
 */
@Component
@Order(-1)
@Slf4j
public class GloableErrorHandler implements ErrorWebExceptionHandler {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        ResultError re = null;
        if (ex instanceof WoniuException){
            WoniuException we = (WoniuException) ex;
            log.error("出现异常 code:{},class:{}", we.getCode(), we.getClass().getName());
            re =  ResultError.errorExec(we);
        }
        else {
            log.error("出现异常 code:{},message:{},class:{}", WoniuExceptionCode.SYS_ERROR.getCode(),
                    ex.getMessage(), ex.getClass().getName());
            re = ResultError.builder().code(WoniuExceptionCode.SYS_ERROR.getCode()).msg(ex.getMessage()).build();
        }

        final ResultError result = re;
        exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
        return exchange.getResponse().writeWith(Mono.fromSupplier(()->{
            byte[] bytes = null;
            try {
                bytes = objectMapper.writeValueAsBytes(result);
            } catch (JsonProcessingException e) {
                throw new WoniuJsonException(WoniuExceptionCode.JSON_PARSE);
            }

            if (ex instanceof WoniuAuthencticationException){
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            } else if (ex instanceof WoniuUnauthencticationException){
                exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            } else if (ex instanceof ResponseStatusException){
                exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
            } else {
                exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
            }

            return exchange.getResponse().bufferFactory().wrap(bytes);
        }));
    }
}

